package com.qiudao.commonutil.util;

import com.google.common.collect.Lists;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;

/**
 * Description: 分批工具类
 * 依赖 com.google.guava.guava
 * @author: gdc
 * @date: 2019/9/1
 * @version 1.0
 */
public class BatchUtils<T> {

    private final static int START_BATCH_NO = 1;

    /**
     * 列表数据
     */
    private List<T> data;

    /**
     * 页号, 从1开始
     */
    private int totalBatch;

    /**
     * 每页大小, 默认50
     */
    private int batchSize;

    public BatchUtils(List<T> data) {
        this(data, 50);
    }

    public BatchUtils(List<T> data, int batchSize) {
        if (CollectionUtils.isEmpty(data)) {
            throw new IllegalArgumentException("data can not be empty.");
        }

        this.data = data;
        this.batchSize = batchSize;
        this.totalBatch = data.size() / batchSize;

        if (data.size() % batchSize != 0) {
            this.totalBatch++;
        }
    }

    public List<T> getDataForBatch(int batchNo) {
        if (batchNo < START_BATCH_NO) {
            throw new IllegalArgumentException("batch no must be greater than " + START_BATCH_NO);
        }

        int fromIndex = (batchNo - 1) * batchSize;
        if (fromIndex >= data.size()) {
            return Collections.emptyList();
        }

        int toIndex = batchNo * batchSize;
        if (toIndex >= data.size()) {
            toIndex = data.size();
        }

        return data.subList(fromIndex, toIndex);
    }

    /**
     * 获取分好批的数据
     *
     * @return
     */
    public List<List<T>> getBatchedData() {
        List<List<T>> batchedData = Lists.newArrayList();

        int currentBatchNo = 1;

        while (true) {
            List<T> batch = getDataForBatch(currentBatchNo);
            if (CollectionUtils.isEmpty(batch)) {
                break;
            }

            batchedData.add(batch);
            currentBatchNo++;
        }
        return batchedData;

    }

    public List<T> getData() {
        return data;
    }

    public int getTotalBatch() {
        return totalBatch;
    }

    public int getBatchSize() {
        return batchSize;
    }

    public boolean onlyOneBatch() {
        return getTotalBatch() == 1;
    }

}

